package com.lws.rxutils.asynconce;

import android.view.View;

import androidx.annotation.CheckResult;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidDisposable;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ViewModel;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Maybe;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.disposables.DisposableContainer;
import io.reactivex.rxjava3.functions.Action;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.schedulers.Schedulers;

public class MaybeRxAsyncOnce<T> {

    private final Maybe<T> maybe;

    MaybeRxAsyncOnce(@NonNull Maybe<T> maybe) {
        this.maybe = maybe.subscribeOn(Schedulers.io());
    }

    @CheckResult
    @NonNull
    public Disposable start(@NonNull Consumer<? super T> onSuccess) {
        return maybe.observeOn(AndroidSchedulers.mainThread())
                .subscribe(onSuccess);
    }

    @CheckResult
    @NonNull
    public Disposable start(@NonNull Consumer<? super T> onSuccess, @NonNull Consumer<Throwable> onError) {
        return maybe.observeOn(AndroidSchedulers.mainThread())
                .subscribe(onSuccess, onError);
    }

    @CheckResult
    @NonNull
    public Disposable start(@NonNull Consumer<? super T> onSuccess, @NonNull Consumer<Throwable> onError, @NonNull Action onComplete) {
        return maybe.observeOn(AndroidSchedulers.mainThread())
                .subscribe(onSuccess, onError, onComplete);
    }


    public void start(@NonNull DisposableContainer container, @NonNull Consumer<? super T> onSuccess) {
        maybe.observeOn(AndroidSchedulers.mainThread())
                .subscribe(onSuccess, Debug::logOnThrowable, Debug::logonComplete, container);
    }

    public void start(@NonNull DisposableContainer container, @NonNull Consumer<? super T> onSuccess, @NonNull Consumer<Throwable> onError) {
        maybe.observeOn(AndroidSchedulers.mainThread())
                .subscribe(onSuccess, onError, Debug::logonComplete, container);
    }


    public void start(@NonNull DisposableContainer container, @NonNull Consumer<? super T> onSuccess, @NonNull Consumer<Throwable> onError, @NonNull Action onComplete) {
        maybe.observeOn(AndroidSchedulers.mainThread())
                .subscribe(onSuccess, onError, onComplete, container);
    }


    public void start(@NonNull LifecycleOwner lifecycleOwner, @NonNull Consumer<? super T> onSuccess) {
        start(AndroidDisposable.from(lifecycleOwner), onSuccess);
    }

    public void start(@NonNull LifecycleOwner lifecycleOwner, @NonNull Consumer<? super T> onSuccess, @NonNull Consumer<Throwable> onError) {
        start(AndroidDisposable.from(lifecycleOwner), onSuccess, onError);
    }


    public void start(@NonNull LifecycleOwner lifecycleOwner, @NonNull Consumer<? super T> onSuccess, @NonNull Consumer<Throwable> onError, @NonNull Action onComplete) {
        start(AndroidDisposable.from(lifecycleOwner), onSuccess, onError, onComplete);
    }


    public void start(@NonNull Lifecycle lifecycle, @NonNull Consumer<? super T> onSuccess) {
        start(AndroidDisposable.from(lifecycle), onSuccess);
    }

    public void start(@NonNull Lifecycle lifecycle, @NonNull Consumer<? super T> onSuccess, @NonNull Consumer<Throwable> onError) {
        start(AndroidDisposable.from(lifecycle), onSuccess, onError);
    }


    public void start(@NonNull Lifecycle lifecycle, @NonNull Consumer<? super T> onSuccess, @NonNull Consumer<Throwable> onError, @NonNull Action onComplete) {
        start(AndroidDisposable.from(lifecycle), onSuccess, onError, onComplete);
    }


    public void start(@NonNull ViewModel viewModel, @NonNull Consumer<? super T> onSuccess) {
        start(AndroidDisposable.from(viewModel), onSuccess);
    }

    public void start(@NonNull ViewModel viewModel, @NonNull Consumer<? super T> onSuccess, @NonNull Consumer<Throwable> onError) {
        start(AndroidDisposable.from(viewModel), onSuccess, onError);
    }


    public void start(@NonNull ViewModel viewModel, @NonNull Consumer<? super T> onSuccess, @NonNull Consumer<Throwable> onError, @NonNull Action onComplete) {
        start(AndroidDisposable.from(viewModel), onSuccess, onError, onComplete);
    }


    public void start(@NonNull View view, @NonNull Consumer<? super T> onSuccess) {
        start(AndroidDisposable.from(view), onSuccess);
    }

    public void start(@NonNull View view, @NonNull Consumer<? super T> onSuccess, @NonNull Consumer<Throwable> onError) {
        start(AndroidDisposable.from(view), onSuccess, onError);
    }


    public void start(@NonNull View view, @NonNull Consumer<? super T> onSuccess, @NonNull Consumer<Throwable> onError, @NonNull Action onComplete) {
        start(AndroidDisposable.from(view), onSuccess, onError, onComplete);
    }
}
